package tool

import (
	"encoding/json"
	"fmt"
	"strconv"

	"github.com/360EntSecGroup-Skylar/excelize"

	"gitee.com/krio/grpc-go-server/cmd/lib"
	"gitee.com/krio/helper/utils"
)

var (
	abcS = []string{"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"} // 不够再添
)

type Excelize struct {
	File      *excelize.File
	SheetName string   // sheet名称
	ColTitles []string // 表格标题
	ColNum    int      // 表格纵列数
	Total     int      // 数据总数
}

func NewExcelize(sheetName string, colTitles []string, total int) *Excelize {
	colNum := len(colTitles)

	return &Excelize{
		File:      excelize.NewFile(),
		SheetName: sheetName,
		ColTitles: colTitles,
		ColNum:    colNum,
		Total:     total,
	}
}

type CellStyle struct {
	Sheet     string
	StartCell string
	EndCell   string
	Style     *Style
}

type CellMerge struct {
	Sheet     string
	StartCell string
	EndCell   string
}

type Style struct {
	Alignment *Alignment `json:"alignment,omitempty"`
	Font      *Font      `json:"font,omitempty"`
	Fill      *Fill      `json:"fill,omitempty"`
	Border    []*Border  `json:"border,omitempty"`
}

type Alignment struct {
	Horizontal string `json:"horizontal,omitempty"` // 水平对齐方式
	Vertical   string `json:"vertical,omitempty"`   // 垂直对齐方式
	WrapText   bool   `json:"wrap_text,omitempty"`  // 自动换行设置
}

type Font struct {
	Bold bool `json:"bold,omitempty"` // 粗体
}

type Fill struct {
	Type    string   `json:"type,omitempty"`    // 填充类型
	Color   []string `json:"color,omitempty"`   // 填充颜色
	Pattern int      `json:"pattern,omitempty"` // 填充模式
}

type Border struct {
	Type  string `json:"type,omitempty"`  // 类型
	Color string `json:"color,omitempty"` // 颜色
	Style int    `json:"style,omitempty"` // 风格
}

func (s *Style) Formatter() string {
	b, err := json.Marshal(s)
	if err != nil {
		return ""
	}
	return string(b)
}

// 标题（合并单元格）
func (e *Excelize) TitleCellMerge(title string) *Excelize {
	// 合并单元格
	cellMerges := make([]*CellMerge, 0)
	cellMerges = append(cellMerges, &CellMerge{
		Sheet:     e.SheetName,
		StartCell: "A1",
		EndCell:   abcS[e.ColNum-1] + "1",
	})

	for _, cellMerge := range cellMerges {
		e.File.MergeCell(cellMerge.Sheet, cellMerge.StartCell, cellMerge.EndCell)
	}

	e.File.SetCellValue(e.SheetName, "A1", title)

	// 设置标题行高度
	e.File.SetRowHeight(e.SheetName, 1, 20)

	return e
}

// 自定义模板样式
func (e *Excelize) SetExampleStyle() *Excelize {
	cellStyles := make([]*CellStyle, 0)
	cellStyles = append(cellStyles, &CellStyle{
		Sheet:     e.SheetName,
		StartCell: "A1",
		EndCell:   abcS[e.ColNum-1] + "1",
		Style: &Style{
			Alignment: &Alignment{
				Horizontal: "center",
				Vertical:   "center",
			},
			Font: &Font{Bold: true},
			Border: []*Border{
				{
					Type:  "left",
					Color: "#000000",
					Style: 1,
				},
				{
					Type:  "right",
					Color: "#000000",
					Style: 1,
				},
				{
					Type:  "top",
					Color: "#000000",
					Style: 1,
				},
				{
					Type:  "bottom",
					Color: "#000000",
					Style: 1,
				},
			},
			Fill: &Fill{
				Type:    "pattern",
				Color:   []string{"#00B0F0"},
				Pattern: 1,
			},
		},
	}, &CellStyle{
		Sheet:     e.SheetName,
		StartCell: "A2",
		EndCell:   abcS[e.ColNum-1] + "2",
		Style: &Style{
			Alignment: &Alignment{
				Horizontal: "center",
				Vertical:   "center",
			},
			Fill: &Fill{
				Type:    "pattern",
				Color:   []string{"#00B050"},
				Pattern: 1,
			},
			Font: &Font{Bold: true},
			Border: []*Border{
				{
					Type:  "left",
					Color: "#000000",
					Style: 1,
				},
				{
					Type:  "right",
					Color: "#000000",
					Style: 1,
				},
				{
					Type:  "top",
					Color: "#000000",
					Style: 1,
				},
				{
					Type:  "bottom",
					Color: "#000000",
					Style: 1,
				},
			},
		},
	}, &CellStyle{
		Sheet:     e.SheetName,
		StartCell: "A3",
		EndCell:   abcS[e.ColNum-1] + strconv.Itoa(e.Total+2),
		Style: &Style{
			Alignment: &Alignment{
				Horizontal: "center",
			},
			Border: []*Border{
				{
					Type:  "left",
					Color: "#000000",
					Style: 1,
				},
				{
					Type:  "right",
					Color: "#000000",
					Style: 1,
				},
				{
					Type:  "top",
					Color: "#000000",
					Style: 1,
				},
				{
					Type:  "bottom",
					Color: "#000000",
					Style: 1,
				},
			},
		},
	})

	for _, cellStyle := range cellStyles {
		style, err := e.File.NewStyle(cellStyle.Style.Formatter())
		if err != nil {
			return nil
		}
		e.File.SetCellStyle(cellStyle.Sheet, cellStyle.StartCell, cellStyle.EndCell, style)
	}

	return e
}

// 列标题
func (e *Excelize) SetColTitle() *Excelize {
	for index, title := range e.ColTitles {
		e.File.SetCellValue(e.SheetName, abcS[index]+"2", title)
	}

	return e
}

func (e *Excelize) FileSaveAs(mode string) (*StorageMessage, error) {
	uuid, err := GetUUID()
	if err != nil {
		return nil, err
	}

	filePath := lib.C.File.URL
	err = utils.MkDirAll(filePath)
	if err != nil {
		return nil, err
	}
	fileName := uuid + ".xlsx"
	if err := e.File.SaveAs(fmt.Sprintf("%s/%s", filePath, fileName)); err != nil {
		return nil, err
	}

	return &StorageMessage{
		URL:      filePath,
		FileName: fileName,
	}, nil
}

type StorageMessage struct {
	URL      string
	FileName string
}
